﻿/**
 * Copyright (c) 2008 Justin Etheredge http://www.codethinked.com
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Microsoft Public License (Ms-PL)
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/ms-pl.html
 * If redistributing this code, this entire header must remain intact.
 * 
 * Some of the code in this application has been taken 
 * from the following sources (all of which are licensed under
 * the Ms-PL):
 * Matt Warren's Blog: http://blogs.msdn.com/mattwar/
 * MSDN: http://msdn2.microsoft.com/en-us/library/bb546158.aspx
 */

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using LinqToSimpleDB;

namespace LinqToSimpleDBTest
{
  /// <summary>
  /// Summary description for SimpleDBAttributeTest
  /// </summary>
  [TestClass]
  public class SimpleDBAttributeTest
  {
    public SimpleDBAttributeTest()
    {
    }

    private TestContext testContextInstance;

    /// <summary>
    ///Gets or sets the test context which provides
    ///information about and functionality for the current test run.
    ///</summary>
    public TestContext TestContext
    {
      get
      {
        return testContextInstance;
      }
      set
      {
        testContextInstance = value;
      }
    }

    #region Additional test attributes
    //
    // You can use the following additional attributes as you write your tests:
    //
    // Use ClassInitialize to run code before running the first test in the class
    // [ClassInitialize()]
    // public static void MyClassInitialize(TestContext testContext) { }
    //
    // Use ClassCleanup to run code after all tests in a class have run
    // [ClassCleanup()]
    // public static void MyClassCleanup() { }
    //
    // Use TestInitialize to run code before running each test 
    // [TestInitialize()]
    // public void MyTestInitialize() { }
    //
    // Use TestCleanup to run code after each test has run
    // [TestCleanup()]
    // public void MyTestCleanup() { }
    //
    #endregion

    [TestMethod]
    public void EqualsOperatorTest()
    {
      SimpleDBAttribute attribute = new SimpleDBAttribute("test", "string");
      Assert.IsTrue(attribute == "string");
      Assert.IsTrue("string" == attribute);

      attribute = new SimpleDBAttribute("test", "0006");
      Assert.IsTrue(attribute == 6);
      Assert.IsFalse(attribute == 5);

      Assert.IsTrue(6 == attribute);
      Assert.IsFalse(5 == attribute);

      attribute = new SimpleDBAttribute("test", "0006.5");
      Assert.IsTrue(attribute == 6.5);
      Assert.IsFalse(attribute == 5.5);

      Assert.IsTrue(6.5 == attribute);
      Assert.IsFalse(5.5 == attribute);

      attribute = new SimpleDBAttribute("test", "true");
      Assert.IsTrue(attribute == true);
      Assert.IsFalse(attribute == false);
      Assert.IsTrue(true == attribute);
      Assert.IsFalse(false == attribute);

      attribute = new SimpleDBAttribute("test", "false");
      Assert.IsTrue(attribute == false);
      Assert.IsFalse(attribute == true);

      attribute = new SimpleDBAttribute("test", "testvalue", "true");
      Assert.IsTrue(attribute == true);
      Assert.IsFalse(attribute == false);

      attribute = new SimpleDBAttribute("test", "testvalue", "false");
      Assert.IsTrue(attribute == false);
      Assert.IsFalse(attribute == true);

      attribute = new SimpleDBAttribute("test", "testvalue");
      Assert.IsFalse(attribute == false);
      Assert.IsFalse(attribute == true);

      attribute = new SimpleDBAttribute("test", "testvalue");
      Assert.IsFalse(attribute == true);
      Assert.IsFalse(attribute == false);
    }

    [TestMethod]
    public void NotEqualsOperatorTest()
    {
      SimpleDBAttribute attribute = new SimpleDBAttribute("test", "string");
      Assert.IsTrue(attribute != "stringy", "String Not Equal 1 Failed.");
      Assert.IsFalse(attribute != "string", "String Not Equal 2 Failed.");

      Assert.IsTrue("stringy" != attribute, "String Not Equal 3 Failed.");
      Assert.IsFalse("string" != attribute, "String Not Equal 4 Failed.");

      attribute = new SimpleDBAttribute("test", "0006");
      Assert.IsFalse(attribute != 6);
      Assert.IsTrue(attribute != 5);

      Assert.IsFalse(6 != attribute);
      Assert.IsTrue(5 != attribute);

      attribute = new SimpleDBAttribute("test", "0006.5");
      Assert.IsFalse(attribute != 6.5);
      Assert.IsTrue(attribute != 5.5);

      Assert.IsFalse(6.5 != attribute);
      Assert.IsTrue(5.5 != attribute);

      attribute = new SimpleDBAttribute("test", "true");
      Assert.IsFalse(attribute != true);
      Assert.IsTrue(attribute != false);
      Assert.IsFalse(true != attribute);
      Assert.IsTrue(false != attribute);

      attribute = new SimpleDBAttribute("test", "false");
      Assert.IsFalse(attribute != false);
      Assert.IsTrue(attribute != true);

      attribute = new SimpleDBAttribute("test", "testvalue", "true");
      Assert.IsTrue(attribute != false);
      Assert.IsFalse(attribute != true);

      attribute = new SimpleDBAttribute("test", "testvalue", "false");
      Assert.IsTrue(attribute != true);
      Assert.IsFalse(attribute != false);

      attribute = new SimpleDBAttribute("test", "testvalue");
      Assert.IsTrue(attribute != false);
      Assert.IsTrue(attribute != true);

      attribute = new SimpleDBAttribute("test", "testvalue");
      Assert.IsTrue(attribute != true);
      Assert.IsTrue(attribute != false);
    }

    [TestMethod]
    public void GreaterThanOperatorTest()
    {
      SimpleDBAttribute attribute = new SimpleDBAttribute("test", "b");
      Assert.IsTrue(attribute > "a", "String Greater Than 1 Failed.");
      Assert.IsFalse(attribute > "c", "String Greater Than 2 Failed.");

      Assert.IsFalse("a" > attribute, "String Greater Than 3 Failed.");
      Assert.IsTrue("c" > attribute, "String Greater Than 4 Failed.");

      SimpleDBAttribute attribute2 = new SimpleDBAttribute("test", "0000006");
      Assert.IsTrue(attribute2 > 4, "Integer Greater Than 5 Failed.");
      Assert.IsFalse(attribute2 > 8, "Integer Greater Than 6 Failed.");

      Assert.IsFalse(4 > attribute2, "Integer Greater Than 7 Failed.");
      Assert.IsTrue(8 > attribute2, "Integer Greater Than 8 Failed.");

      SimpleDBAttribute attribute3 = new SimpleDBAttribute("test", "0000006.5");
      Assert.IsTrue(attribute3 > 5.5, "Integer Greater Than 5 Failed.");
      Assert.IsFalse(attribute3 > 8.5, "Integer Greater Than 6 Failed.");

      Assert.IsFalse(5.5 > attribute3, "Integer Greater Than 5 Failed.");
      Assert.IsTrue(8.5 > attribute3, "Integer Greater Than 6 Failed.");
    }

    [TestMethod]
    public void LessThanOperatorTest()
    {
      SimpleDBAttribute attribute = new SimpleDBAttribute("test", "b");
      Assert.IsFalse(attribute < "a", "String Greater Than 1 Failed.");
      Assert.IsTrue(attribute < "c", "String Greater Than 2 Failed.");

      Assert.IsTrue("a" < attribute, "String Greater Than 3 Failed.");
      Assert.IsFalse("c" < attribute, "String Greater Than 4 Failed.");

      SimpleDBAttribute attribute2 = new SimpleDBAttribute("test", "0000006");
      Assert.IsFalse(attribute2 < 4, "Integer Greater Than 5 Failed.");
      Assert.IsTrue(attribute2 < 8, "Integer Greater Than 6 Failed.");

      Assert.IsTrue(4 < attribute2, "Integer Greater Than 7 Failed.");
      Assert.IsFalse(8 < attribute2, "Integer Greater Than 8 Failed.");

      SimpleDBAttribute attribute3 = new SimpleDBAttribute("test", "0000006.5");
      Assert.IsFalse(attribute3 < 5.5, "Integer Greater Than 5 Failed.");
      Assert.IsTrue(attribute3 < 8.5, "Integer Greater Than 6 Failed.");

      Assert.IsTrue(5.5 < attribute3, "Integer Greater Than 5 Failed.");
      Assert.IsFalse(8.5 < attribute3, "Integer Greater Than 6 Failed.");
    }

    [TestMethod]
    public void GreaterThanEqualToOperatorTest()
    {
      SimpleDBAttribute attribute = new SimpleDBAttribute("test", "b");
      Assert.IsTrue(attribute >= "a");
      Assert.IsTrue(attribute >= "b");
      Assert.IsFalse(attribute >= "c");

      Assert.IsFalse("a" >= attribute);
      Assert.IsTrue("b" >= attribute);
      Assert.IsTrue("c" >= attribute);

      SimpleDBAttribute attribute2 = new SimpleDBAttribute("test", "0000006");
      Assert.IsTrue(attribute2 >= 4);
      Assert.IsTrue(attribute2 >= 6);
      Assert.IsFalse(attribute2 >= 8);

      Assert.IsFalse(4 >= attribute2);
      Assert.IsTrue(6 >= attribute2);
      Assert.IsTrue(8 >= attribute2);

      SimpleDBAttribute attribute3 = new SimpleDBAttribute("test", "0000006.5");
      Assert.IsTrue(attribute3 >= 5.5);
      Assert.IsTrue(attribute3 >= 6.5);
      Assert.IsFalse(attribute3 >= 8.5);

      Assert.IsFalse(5.5 >= attribute3);
      Assert.IsTrue(6.5 >= attribute3);
      Assert.IsTrue(8.5 >= attribute3);
    }

    [TestMethod]
    public void LessThanEqualToOperatorTest()
    {
      SimpleDBAttribute attribute = new SimpleDBAttribute("test", "b");
      Assert.IsFalse(attribute <= "a");
      Assert.IsTrue(attribute <= "b");
      Assert.IsTrue(attribute <= "c");

      Assert.IsTrue("a" <= attribute);
      Assert.IsTrue("b" <= attribute);
      Assert.IsFalse("c" <= attribute);

      SimpleDBAttribute attribute2 = new SimpleDBAttribute("test", "0000006");
      Assert.IsFalse(attribute2 <= 4);
      Assert.IsTrue(attribute2 <= 6);
      Assert.IsTrue(attribute2 <= 8);

      Assert.IsTrue(4 <= attribute2);
      Assert.IsTrue(6 <= attribute2);
      Assert.IsFalse(8 <= attribute2);

      SimpleDBAttribute attribute3 = new SimpleDBAttribute("test", "0000006.5");
      Assert.IsFalse(attribute3 <= 5.5);
      Assert.IsTrue(attribute3 <= 6.5);
      Assert.IsTrue(attribute3 <= 8.5);

      Assert.IsTrue(5.5 <= attribute3);
      Assert.IsTrue(6.5 <= attribute3);
      Assert.IsFalse(8.5 <= attribute3);
    }

    /// <summary>
    ///A test for SimpleDBAttribute Constructor
    ///</summary>
    [TestMethod()]
    public void SimpleDBAttributeEmptyConstructorTest()
    {
      SimpleDBAttribute target = new SimpleDBAttribute();
      Assert.IsTrue(target.Name == string.Empty);
      Assert.IsNull(target.Values);
    }

    [TestMethod()]
    public void SimpleDBAttributeAccessNameTest()
    {
      SimpleDBAttribute target = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      Assert.IsTrue(target.Name == "testname");
      Assert.IsTrue(target.Values != null);

      Assert.IsTrue(target.Values[0] == "testparam1");
      Assert.IsTrue(target.Values[1] == "testparam2");
    }

    [TestMethod()]
    public void SimpleDBAttributeIsNumericTest()
    {
      SimpleDBAttribute target = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      Assert.IsFalse(target.IsNumeric, "Should not be numeric.");

      target = new SimpleDBAttribute("testname2", "1.4", "abc");
      Assert.IsTrue(target.IsNumeric, "Should be numeric.");
    }

    [TestMethod()]
    public void SimpleDBAttributeEqualsTest()
    {
      SimpleDBAttribute target = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      SimpleDBAttribute target2 = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      Assert.IsTrue(target.Equals(target2), "Should be equal.");

      target = new SimpleDBAttribute("testname", "5.1");
      var objTarget = new Object();
      Assert.IsFalse(target.Equals(objTarget), "Should not be equal.");

      target = new SimpleDBAttribute("testname", "5.1");
      target2 = new SimpleDBAttribute("testname", "5.1");
      Assert.IsTrue(target.Equals(target2), "Should be equal.");

      target = new SimpleDBAttribute("testname", "5.1");
      target2 = new SimpleDBAttribute("testname", "test");
      Assert.IsFalse(target.Equals(target2), "Should be not equal.");

      target = new SimpleDBAttribute("testname", "5.1", "5.3");
      target2 = new SimpleDBAttribute("testname", "5.1", "5.3");
      Assert.IsTrue(target.Equals(target2), "Should be equal.");

      target = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      target2 = new SimpleDBAttribute("testname", "testparam3", "testparam2");
      Assert.IsFalse(target.Equals(target2), "Should not be equal.");

      target = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      target2 = new SimpleDBAttribute("testname", "testparam1", "testparam3");
      Assert.IsFalse(target.Equals(target2), "Should not be equal.");

      target = new SimpleDBAttribute("testname", "5.1", "testparam2");
      target2 = new SimpleDBAttribute("testname", "5.1", "testparam2");
      Assert.IsTrue(target.Equals(target2), "Should be equal.");

      target = new SimpleDBAttribute("testname", "5.2", "testparam2");
      target2 = new SimpleDBAttribute("testname", "5.1", "testparam2");
      Assert.IsFalse(target.Equals(target2), "Should not be equal.");

      target = new SimpleDBAttribute("testname", "5.2");
      target2 = new SimpleDBAttribute("testname", "5.1", "4.4");
      Assert.IsFalse(target.Equals(target2), "Should not be equal.");

      target = new SimpleDBAttribute("testname", "5.1");
      target2 = new SimpleDBAttribute("testname", "5.1", "testparam2");
      Assert.IsFalse(target.Equals(target2), "Should not be equal.");

      target = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      target2 = new SimpleDBAttribute("testname", "testparam1");
      Assert.IsFalse(target.Equals(target2), "Should not be equal.");
    }

    [TestMethod()]
    public void SimpleDBAttributeGetHashCodeTest()
    {
      SimpleDBAttribute target = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      SimpleDBAttribute target2 = new SimpleDBAttribute("testname", "testparam1", "testparam2");
      int hashcode1 = target.GetHashCode();
      int hashcode2 = target2.GetHashCode();
      Assert.IsTrue(hashcode1 == hashcode2, "Should be equal. Actual: {0} Expected: {1}", hashcode1, hashcode2);
    }

    [TestMethod()]
    public void SimpleDBAttributeMarkDeletedTest()
    {
      var target = new SimpleDBAttribute("test", "test1");
      Assert.IsFalse(((IDeletable)target).IsDeleted, "Should not be marked as deleted.");
      ((IDeletable)target).MarkDeleted();
      Assert.IsTrue(((IDeletable)target).IsDeleted, "Should be marked as deleted.");
    }

    [TestMethod()]
    public void SimpleDBAttributeIsDirtyTest()
    {
      var target = new SimpleDBAttribute("test", "test1");
      Assert.IsTrue(((IDirtyTrackable)target).IsDirty, "Should be marked dirty");
      ((IDirtyTrackable)target).MarkClean();
      Assert.IsFalse(((IDirtyTrackable)target).IsDirty, "Should not be marked dirty");
      ((IDirtyTrackable)target).MarkDirty();
      Assert.IsTrue(((IDirtyTrackable)target).IsDirty, "Should be marked dirty");
    }

    [TestMethod()]
    public void SimpleDBAttributeWithValueTest()
    {
      var target = new SimpleDBAttribute("test")
        .WithValue("test1")
        .WithValue("test2");

      Assert.IsTrue(target.Values.Length == 2, "Length is wrong");
      Assert.IsTrue(target.Values[0] == "test1");
      Assert.IsTrue(target.Values[1] == "test2");

      target.WithValue("test3");

      Assert.IsTrue(target.Values.Length == 3, "Length is wrong");
      Assert.IsTrue(target.Values[0] == "test1");
      Assert.IsTrue(target.Values[1] == "test2");
      Assert.IsTrue(target.Values[2] == "test3");
    }

    [TestMethod()]
    public void SimpleDBAttributeAddValueTest()
    {
      var target = new SimpleDBAttribute("test");
      target.AddValue("test1");
      target.AddValue("test2");

      Assert.IsTrue(target.Values.Length == 2, "Length is wrong");
      Assert.IsTrue(target.Values[0] == "test1");
      Assert.IsTrue(target.Values[1] == "test2");

      target.AddValue("test3");

      Assert.IsTrue(target.Values.Length == 3, "Length is wrong");
      Assert.IsTrue(target.Values[0] == "test1");
      Assert.IsTrue(target.Values[1] == "test2");
      Assert.IsTrue(target.Values[2] == "test3");
    }

    [TestMethod()]
    public void OperandsDecimalTest()
    {
      SimpleDBAttribute c1 = new SimpleDBAttribute("test", "15");
      Assert.IsTrue(c1 == 15M);
      Assert.IsTrue(15M == c1);
      Assert.IsFalse(c1 == 16M);
      Assert.IsFalse(16M == c1);

      Assert.IsFalse(c1 > 15M);
      Assert.IsFalse(15M > c1);
      Assert.IsTrue(c1 > 14M);
      Assert.IsTrue(16M > c1);

      Assert.IsFalse(c1 < 15M);
      Assert.IsFalse(15M < c1);
      Assert.IsTrue(c1 < 16M);
      Assert.IsTrue(14M < c1);

      Assert.IsTrue(c1 >= 15M);
      Assert.IsTrue(15M >= c1);
      Assert.IsFalse(c1 >= 16M);
      Assert.IsTrue(c1 >= 14M);
      Assert.IsTrue(16M >= c1);

      Assert.IsTrue(c1 <= 15M);
      Assert.IsTrue(15M <= c1);
      Assert.IsFalse(c1 <= 14M);
      Assert.IsTrue(c1 <= 16M);
      Assert.IsTrue(14M <= c1);

      c1 = new SimpleDBAttribute("test", "test1");
      Assert.IsFalse(c1 == 15M);
      Assert.IsFalse(15M == c1);
    }

    [TestMethod()]
    public void OperandsStringTest()
    {
      SimpleDBAttribute c1 = new SimpleDBAttribute("test", "test1");
      Assert.IsTrue(c1 == "test1");
      Assert.IsTrue("test1" == c1);
      Assert.IsFalse(c1 == "test2");
      Assert.IsFalse("test2" == c1);
    }

    [TestMethod()]
    public void OperandsDoubleTest()
    {
      SimpleDBAttribute c1 = new SimpleDBAttribute("test", "13", "15.2");
      Double val = 15.2;
      Assert.IsTrue(c1 == val);
      Assert.IsTrue(val == c1);
    }

    [TestMethod()]
    public void OperandsInt32Test()
    {
      SimpleDBAttribute c1 = new SimpleDBAttribute("test", "13", "15");
      int val = 15;
      Assert.IsTrue(c1 == val);
      Assert.IsTrue(val == c1);
    }

    [TestMethod()]
    public void StartsWithTest()
    {
      SimpleDBAttribute c1 = new SimpleDBAttribute("test", "testvalue1", "blahhh");
      Assert.IsTrue(c1.StartsWith("testval"));
      Assert.IsFalse(c1.StartsWith("cre"));
      Assert.IsTrue(c1.StartsWith("bla"));
    }
  }
}
